/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *  SRVUIJoypadTouchControlView.m - iPhoneSRV console for Surveyor SRV-1 and SVS 
 *
 *  Created by Nick Kitchener.  Copyright (C) 2009  Surveyor Corporation 
 *            and Nick Kitchener.  All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details (www.gnu.org/licenses)
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#import "SRVUIJoypadTouchControlView.h"

// Joypad use description
// Place finger in area for 2 seconds, the joypad will activate and draw an animation of centre point, maximum radius and X,Y axis with small intervals. Joypad callback
// activation event issued.
// move finger around as required, the red dot will follow under your finger. The joypad callback will be notified of the change in values.
// take finger off - the red dot will remain at the last point you touched. The joypad callback will be notified of the finger lift.
// place finger on again within 5 seconds and the dot will move to that location and follow. Again the joypad callback will be notified of the change in values.
// if the finger is taken off for longer than 5 seconds then the joypad will fade out over 5 seconds. Joypad callback deactivation event issued at the end of the time.

#define ACTIVATION_TIME 2
#define DEACTIVATION_DELAY 5
#define DEACTIVATION_TIME 5

@implementation SRVUIJoypadTouchControlView
@synthesize controlled;

- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
		gesture = [[SRVUIJoypadGestureRecognizer alloc]initWithJoypad:self];
        // Initialization code
		[self setOpaque:NO];
		[self setAlpha:0.0];
		joypadRectangle.origin.x = frame.origin.x;
		joypadRectangle.origin.y = frame.origin.y;
		joypadRectangle.size.width = frame.size.width;
		joypadRectangle.size.height = frame.size.height;
	
		[self setNeedsDisplay];
    }
    return self;
}

- (void)dealloc {
    [super dealloc];
}

- (void)drawRect:(CGRect)rect {
    // Drawing code
	// get context
	CGContextRef context = UIGraphicsGetCurrentContext();
	
	float midX = joypadRectangle.size.width/2;
	float midY = joypadRectangle.size.height/2;
	
	CGContextClearRect(context, rect);
	
	// draw graduated circle - an outside path, then a graduated line x=0,y=0
	CGContextSetLineWidth(context, 2.0);
	CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
	
	// draw circle of joypad
	CGContextMoveToPoint(context, midX, midY);
	CGContextAddArc(context, midX, midY, midX, 0.0, 360.0, 0);
	CGContextStrokePath(context);
	
	// X=0
	CGContextMoveToPoint(context, midX, midY-midX);
	CGContextAddLineToPoint(context, midX, midY+midX);
	// Y=0
	CGContextMoveToPoint(context, 0, midY);
	CGContextAddLineToPoint(context, midX*2, midY);
	CGContextStrokePath(context);
	
	// draw current position of joypad (hopefully under the finger)
	float xPos = xValue;
	float yPos = yValue;
	CGContextAddArc(context, xPos, yPos, 10.0, 0.0, 360.0, 0);
	CGContextStrokePath(context);
	
	//CGContextRelease(context);
}


// joypad active
-(void)joypadActivated {
}

// values changed (this will be a frequent call)
-(void)joypadValuesChanged:(NSInteger)x y:(NSInteger)y {
	xValue = x;
	yValue = y;
	[self setNeedsDisplay];
}

// this can be called at any point when active indicating the users finger lifted (can be used to all stop)
-(void)joypadFingerLifted {
}

// joypad deactivated
-(void)joypadDeactivated {
}

@end

@implementation SRVUIJoypadGestureRecognizer

- (id)initWithJoypad:(<SRVUIJoypadTouchControlled>)joypad {
	if( self==[super init] ) {
		target = joypad;
		active = NO;
		activationTimer=nil;
		deactivationTimer=nil;
	}
	return self;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
	if( activationTimer==nil ) {
		activationTimer = [[NSTimer scheduledTimerWithTimeInterval:ACTIVATION_TIME
															target:self
														  selector:@selector(activationTimerFired:)
														  userInfo:nil
														   repeats:NO] retain];
	}
}
- (void)activationTimerFired:(NSTimer*)theTimer {
	active = YES;
	NSLog(@"joypad activated");
	[activationTimer release];
	activationTimer=nil;
	[target joypadActivated];
}


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
	if(active) {
		UITouch *touch = [touches anyObject];
		CGPoint t = [touch locationInView:(SRVUIJoypadTouchControlView*) target];
		
		NSLog(@" touch (%f, %f)", t.x, t.y);
		[target joypadValuesChanged:t.x y:t.y];
	}	
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
	if(active) {
		if( deactivationTimer==nil )
			deactivationTimer = [[NSTimer scheduledTimerWithTimeInterval:DEACTIVATION_TIME
																  target:self
																selector:@selector(deactivationTimerFired:)
																userInfo:nil
																 repeats:NO] retain];
	}
}
- (void)deactivationTimerFired:(NSTimer*)theTimer {
	NSLog(@"joypad deactivated");
	[deactivationTimer release];
	deactivationTimer = nil;
	[target joypadDeactivated];
	active=NO;
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
}

- (void)reset {
}

- (void)ignoreTouch:(UITouch *)touch forEvent:(UIEvent *)event {
}

- (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer *)preventingGestureRecognizer {
	return YES;
}

- (BOOL)canPreventGestureRecognizer:(UIGestureRecognizer *)preventedGestureRecognizer {
	return NO;
}

@end
